package eggcatcher;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class EggCatchAdvanced extends JFrame implements
		KeyListener, ActionListener {
	// Define named-constants
	private static final int CANVAS_WIDTH = 750;
	private static final int CANVAS_HEIGHT = 500;

	private DrawCanvas canvas; // the drawing canvas (extends JPanel)

	ArrayList<Chick> ChickList = new ArrayList<Chick>();
	ArrayList<Egg> BreakEggList = new ArrayList<Egg>();
	int k = 0, pos = 0, basketWidth;
	public static Basket baskets;
	private Image image;
	private Graphics second;
	public static boolean gamesStart;
	boolean flag = false;
	Thread fall;
	boolean th1, th2, th3;
	int x, y, score, lives;
	int locx, locy;
	int plus1, plus2, plus3, count, height, width, random;
	private Image basket;
	private Image chick[];
	private int EggBreakNum;
	private boolean gameOver;
	JButton playButton;
	JButton stopButton;
	JPanel playPanel, stopPanel, buttonPanel;
	private JFrame frame;
	private Thread thread;

	public void initComponent() {

		//addMouseListener(this);
		addKeyListener(this);
		this.gamesStart = false; // initialization
		this.count = 0;
		this.random = 0;
		this.score = 0;
		this.lives = 3;
		this.EggBreakNum = 0;
		this.gameOver = false;

		try {
			basket = ImageIO.read(getClass().getResourceAsStream("Ro.png"));
			chick = new Image[3];
			chick[0] = ImageIO.read(getClass().getResourceAsStream("ga.png"));
			chick[1] = ImageIO.read(getClass().getResourceAsStream("vit.png"));
			chick[2] = ImageIO.read(getClass().getResourceAsStream("ngan.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// setSize(800, 600);
		// getting width and height
		width = getWidth();
		height = getHeight();
		this.basketWidth = basket.getWidth(this) / 2;
		baskets = new Basket(200, 500);
		


		playPanel = new JPanel();
		stopPanel = new JPanel();

		playButton = new JButton("play");
		playButton.addActionListener(this);
		playPanel.setLayout(new FlowLayout());
		playPanel.add(playButton);
		// playPanel.setBounds(500,600, 80, 30);
		// playButton.setBounds(0,0, 80, 30);

		stopButton = new JButton("stop");
		stopButton.addActionListener(this);
		stopPanel.setLayout(new FlowLayout());

		stopPanel.add(stopButton);
		// stopPanel.setLocation(20,20);

		getContentPane().setLayout(new BorderLayout());
		setSize(900, 700);
		// add(playPanel);
		canvas = new DrawCanvas();
		canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
		// canvas.setLayout(new FlowLayout());
		add(canvas, BorderLayout.WEST);

		buttonPanel = new JPanel();
		buttonPanel.setLayout(new BorderLayout());

		JPanel subPanel = new JPanel();
		subPanel.add(playPanel);
		subPanel.add(stopPanel);
		buttonPanel.add(subPanel);

		add(buttonPanel, BorderLayout.CENTER);
		setFocusable(true);
		playButton.setFocusable(false);
		stopButton.setFocusable(false);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setTitle("Egg Catcher");
		setVisible(true);
	}

	/** Constructor to setup the GUI components */
	public EggCatchAdvanced() {
		super();
		initComponent();
		// Define an ActionListener to perform update at regular interval
		thread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				pos = (int) (Math.random() * 10);

				synchronized (this) {
					while (true) {
						if (gamesStart) {
							outerLoop: for (int m = 0; m < ChickList.size(); m++) {
								Chick chick = ChickList.get(m);
								for (int n = 0; n < ChickList.get(m).getItem()
										.size(); n++) {
									Item i = ChickList.get(m).getItem().get(n);

									i.update();

									if (i instanceof Egg // is Egg and not in
															// basket
											&& !baskets.getEggsList().contains(
													(Egg) i)) {

										if (checkEggState((Egg) i).equals(
												EggState.fallingIn)) {
											((Egg) i).State = EggState.fallingIn;
											baskets.addEgg((Egg) i);
										} else if (checkEggState((Egg) i)
												.equals(EggState.fallingOut)) {
											((Egg) i).State = EggState.fallingOut;
											if (i.getImage()!=null)
												EggBreakNum++;
											//System.out.print(EggBreakNum);

										} else
											((Egg) i).State = EggState.fallingAir;

									} else if (i instanceof Shit
											&& !baskets.getEggsList().contains(
													(Shit) i))
										if (checkEggState((Shit) i).equals(
												EggState.fallingIn)) {
											((Shit) i).State = EggState.fallingIn;
											baskets.addShit((Shit) i);
										} else if (checkEggState((Shit) i)
												.equals(EggState.fallingOut)) {
											((Shit) i).State = EggState.fallingOut;
											// EggBreakNum++;

										} else
											((Shit) i).State = EggState.fallingAir;
									if (baskets.getShitsList().size() == 3
											|| EggBreakNum == 3) {
										gamesStart = false;
										gameOver = true;
										break outerLoop;

									}

								}
								ChickList.get(m).clearItemList();

							}

							repaint();

							/*if (baskets.getEggsList().size() > 0
									&& baskets.getEggsList().size() % 20 == 0) // increase
																				// speed
																				// each
																				// 20
																				// //
																				// eggs
							{
								for (int m = 0; m < ChickList.size(); m++) {

									for (int n = 0; n < ChickList.get(m)
											.getItem().size(); n++) {
										Item i = ChickList.get(m).getItem()
												.get(n);
										i.setSpeed(i.getSpeed() + 3);
									}
								}
							}*/

							try {
								Thread.sleep(50);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							if (gameOver)
							{
								removeMouseListener(baskets);
								removeMouseMotionListener(baskets);
								playButton.setEnabled(true);
								for (int m = 0; m < ChickList.size(); m++) {
									Chick chick = ChickList.get(m);
									chick.timer.cancel();
									chick.timer.purge();
								}
								//gamesStart = false;
							}

						}
						/*
						 * else { ChickList.clear(); repaint(); }
						 */
					}

				}

			}
		});
		thread.start();

	}

	/**
	 * This function is use to check the state of egg. Each egg has three state 
	 * (fallingIn, fallingOut, fallingAir)
	 * @param egg
	 * @return
	 */
	public EggState checkEggState(Item egg) {

		// System.out.print(egg.getPosX());
		if ((egg.getPosX() < (baskets.getPosX() - basket.getWidth(this) / 2) + 50 || egg
				.getPosX() > baskets.getPosX() + basket.getWidth(this) / 2 + 25)
				&& egg.getPosY() > baskets.getPosY() - basket.getHeight(this) // egg
																				// fall
																				// out
																				// basket
						/ 2) // and egg fall exceed
			return EggState.fallingOut; // above side of basket
		else if ((egg.getPosX() > (baskets.getPosX() - basket.getWidth(this) / 2) + 50 || egg
				.getPosX() < baskets.getPosX() + basket.getWidth(this) / 2 + 20)
				&& egg.getPosY() > baskets.getPosY() - basket.getHeight(this) // egg
																				// fall
																				// out
																				// basket
						/ 2)
			return EggState.fallingIn;
		else
			return EggState.fallingAir;

	}

	/** DrawCanvas (inner class) is a JPanel used for custom drawing */
	@SuppressWarnings("serial")
	private class DrawCanvas extends JPanel {

		@Override
		public void update(Graphics g) {
			if (image == null) {
				image = createImage(EggCatchAdvanced.this.getWidth(),
						EggCatchAdvanced.this.getHeight());
				second = image.getGraphics();
			}

			second.setColor(getBackground());
			second.fillRect(0, 0, getWidth(), getHeight());
			second.setColor(getForeground());
			paint(second);

			g.drawImage(image, 0, 0, this);

		}

		@Override
		public void paintComponent(Graphics g) {
			super.paintComponent(g); // paint parent's background
			setBackground(Color.WHITE);
			g.setColor(Color.RED);

			for (Chick chick : ChickList) {
				g.drawImage(chick.getImage(), chick.getPosX(), chick.getPosY(),
						this);
				for (Item i : chick.getItem())
				{
					//System.out.println(i.getClass().getName());
					//System.out.println(i.getImage().toString());
					g.drawImage(i.getImage(), i.getPosX(), i.getPosY(), this);
				}

				// chick.isCreate=true;

			}

			g.drawImage(basket, baskets.getPosX(), baskets.getPosY(), this);
			//System.out.println("EggBreak"+EggBreakNum);

			g.drawString("Egg Break Num: " + EggBreakNum, 600, 350);

			g.drawString("Eggs Collected: " + baskets.getEggsList().size(), 600,
					400);

			if (gameOver)
				g.drawString("Game Over", 600, 450);

			g.drawString("Shits Collected: " + baskets.getShitsList().size(), 600, 500);

		}
	}

	/** The entry main method */
	public static void main(String[] args) {
		// Run GUI codes in Event-Dispatching thread for thread safety
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new EggCatchAdvanced(); // Let the constructor do the job
			}
		});
	}

	/**
	 * This function is called when user click button
	 * @param e
	 */
	@Override
	public void actionPerformed(ActionEvent e) {

		if (e.getSource().equals(playButton)) {
			gameOver=false;
			ChickList.clear();
			EggBreakNum = 0;
			score = 0;
			baskets.getEggsList().clear();
			baskets.getShitsList().clear();
			gamesStart = true;
			playButton.setEnabled(false);
			addMouseListener(baskets);
			addMouseMotionListener(baskets);

		} else if (e.getSource().equals(stopButton)) {
			if (gamesStart) {
				removeMouseListener(baskets);
				removeMouseMotionListener(baskets);
				playButton.setEnabled(true);
				for (int m = 0; m < ChickList.size(); m++) {
					Chick chick = ChickList.get(m);
					chick.timer.cancel();
					chick.timer.purge();
				}
				gamesStart = false;
			}

		}

	}

	/**
	 * This function is called when user press a key on the keyboard
	 * @param e
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyChar() == 'g' || e.getKeyChar() == 'G') {
			// Item t = new Egg(70 + k, 100, 5, EggResizedImage);
			ArrayList<Item> ItemList = new ArrayList<Item>();

			Chick chicks = new Chick(50, 50, ItemList, chick[0]);

			ChickList.add(chicks);
			// k += 100;
		}
		if (e.getKeyChar() == 'v' || e.getKeyChar() == 'V') {
			// Item t = new Egg(70 + k, 100, 5, EggResizedImage);
			ArrayList<Item> ItemList = new ArrayList<Item>();
			// ItemList.add(t);

			Chick chicks = new Chick(50 + k, 50, ItemList, chick[1]);

			ChickList.add(chicks);
			// k += 100;
		}
		if (e.getKeyChar() == 'n' || e.getKeyChar() == 'N') {
			// Item t = new Egg(70 + k, 100, 5, EggResizedImage);
			ArrayList<Item> ItemList = new ArrayList<Item>();
			// ItemList.add(t);

			Chick chicks = new Chick(50 + k, 50, ItemList, chick[2]);

			ChickList.add(chicks);
			// k += 100;
		}
		switch (e.getKeyCode()) {
		case KeyEvent.VK_UP:
			System.out.println("Move up");
			break;

		case KeyEvent.VK_DOWN:
			System.out.println("Move down");
			break;

		case KeyEvent.VK_LEFT:
			// System.out.println("Move left");
			if (gamesStart) {
				baskets.moveLeft();
				if (baskets.getPosX() < 20)
					baskets.setPosX(20);
			}
			break;

		case KeyEvent.VK_RIGHT:
			// System.out.println("Move right");
			if (gamesStart) {
				baskets.moveRight();
				if (baskets.getPosX() > 430)
					baskets.setPosX(430);
			}
			break;

		case KeyEvent.VK_SPACE:
			//System.out.println("Jump");
			break;

		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	
}
